package library.frame;

import library.logic.ManagementSystem;
import library.logic.Reader;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Vector;

/**
 * User: RockCrazy
 * Date: 03.01.12
 * Time: 1:37
 */
public class WinReader extends JDialog implements ActionListener
{
	// Владелец нашего окна - вводим для вызова нужного нам метода
	private MainFrame owner;

	// Результат нажатия кнопок
	private boolean result = false;

	// Параметры читателя
	private int readerId = 0;
	private JTextField readerFam = new JTextField();
	private JTextField readerName = new JTextField();
	private JTextField readerOtch = new JTextField();

	private JSpinner readerBirthday = new JSpinner(new SpinnerDateModel(new Date(), null, null, Calendar.DAY_OF_MONTH));
	private JSpinner readerDateReg = new JSpinner(new SpinnerDateModel(new Date(), null, null, Calendar.DAY_OF_MONTH));

	private JTextField readerPassport = new JTextField();
	private JTextField readerAdress = new JTextField();
	private JTextField readerPhone = new JTextField();

	// Параметры окна
	private static final int D_HEIGHT = 550;    // высота окна
	private final static int D_WIDTH = 450;     // ширина окна
	private final static int L_X = 10;          // левая граница метки для поля
	private final static int L_W = 100;         // ширина метки для поля
	private final static int C_W = 150;         // ширина поля
	private ManagementSystem ms;
	private JTable readersTab;

	/**
	 * @param newReader знак добавления читателя или исправление
	 * @param owner родительская форма
	 */
	public WinReader(boolean newReader, MainFrame owner)
	{
		// После вставки читателя без закрытия окна нам потребуется перегрузка списка
		// А для этого нам надо иметь доступ к этому методу в главной форме
		this.owner = owner;
		try
		{
			ms = new ManagementSystem();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		// Установить заголовок
		setTitle("Информация о Читателях");

		// Не будем использовать layout совсем
		getContentPane().setLayout(null);

		// Разместим компоненты по абсолютным координатам

		// Фамилия
		JLabel lFam = new JLabel("Фамилия:", JLabel.RIGHT);
		lFam.setBounds(L_X, 10, L_W, 20);
		getContentPane().add(lFam);
		readerFam.setBounds(L_X + L_W + 10, 10, C_W, 20);
		getContentPane().add(readerFam);

		// имя
		JLabel lName = new JLabel("Имя:", JLabel.RIGHT);
		lName.setBounds(L_X, 35, L_W, 20);
		getContentPane().add(lName);
		readerName.setBounds(L_X + L_W + 10, 35, C_W, 20);
		getContentPane().add(readerName);

		// отчество
		JLabel lOtch = new JLabel("Отчество:", JLabel.RIGHT);
		lOtch.setBounds(L_X, 60, L_W, 20);
		getContentPane().add(lOtch);
		readerOtch.setBounds(L_X + L_W + 10, 60, C_W, 20);
		getContentPane().add(readerOtch);

		// День рождения
		JLabel lBirthday = new JLabel("День рождения:", JLabel.RIGHT);
		lBirthday.setBounds(L_X, 85, L_W, 20);
		getContentPane().add(lBirthday);
		readerBirthday.setBounds(L_X + L_W + 10, 85, C_W, 20);
		getContentPane().add(readerBirthday);

		// Дата регистрации
		JLabel lDateReg = new JLabel("Дата регистрации:", JLabel.RIGHT);
		lDateReg.setBounds(L_X, 110, L_W, 20);
		getContentPane().add(lDateReg);
		readerDateReg.setBounds(L_X + L_W + 10, 110, C_W, 20);
		getContentPane().add(readerDateReg);

		// Паспорт
		JLabel lPassport = new JLabel("Паспорт:", JLabel.RIGHT);
		lPassport.setBounds(L_X, 135, L_W, 20);
		getContentPane().add(lPassport);
		readerPassport.setBounds(L_X + L_W + 10, 135, C_W, 20);
		getContentPane().add(readerPassport);

		// Адрес
		JLabel lAdr = new JLabel("Адрес:", JLabel.RIGHT);
		lAdr.setBounds(L_X, 160, L_W, 20);
		getContentPane().add(lAdr);
		readerAdress.setBounds(L_X + L_W + 10, 160, C_W, 20);
		getContentPane().add(readerAdress);

		// Телефон
		JLabel lTelf = new JLabel("Телефон:", JLabel.RIGHT);
		lTelf.setBounds(L_X, 185, L_W, 20);
		getContentPane().add(lTelf);
		readerPhone.setBounds(L_X + L_W + 10, 185, C_W, 20);
		getContentPane().add(readerPhone);

		// Создаем таблицу для вывода списка клиентов
		readersTab = new JTable(1, 5);
		readersTab.getSelectionModel().addListSelectionListener(new RowListener());
		reloadReaders();
		JScrollPane scrollPane = new JScrollPane(readersTab);
		scrollPane.setBounds(L_X, 210, 420, 300);
		getContentPane().add(scrollPane);


		JButton btnCancel = new JButton("Выход");
		btnCancel.setName("Выход");
		btnCancel.addActionListener(this);
		btnCancel.setBounds(L_X + L_W + C_W + 10 + 50, 43, 100, 25);
		getContentPane().add(btnCancel);

		// если newReader = true
		if (newReader)
		{
			JButton btnOk = new JButton("OK");
			btnOk.setName("OK");
			btnOk.addActionListener(this);
			btnOk.setBounds(L_X + L_W + C_W + 10 + 50, 10, 100, 25);
			getContentPane().add(btnOk);

			JButton btnNew = new JButton("Добавить");
			btnNew.setName("Добавить");
			btnNew.addActionListener(this);
			btnNew.setBounds(L_X + L_W + C_W + 10 + 50, 73, 100, 25);
			getContentPane().add(btnNew);
		}
		// если newReader = false
		else
		{
			JOptionPane.showMessageDialog(this, "<html><font color=red>Внимание! Включен режим редактирования!");
			JButton btnDel = new JButton("<html><font color=red>Удалить");
			btnDel.setName("Удалить");
			btnDel.addActionListener(this);
			btnDel.setBounds(L_X + L_W + C_W + 10 + 50, 10, 100, 25);
			getContentPane().add(btnDel);

			setTitle("Редактирование читателей");
			JButton btnSave = new JButton("Сохранить");
			btnSave.setName("Сохранить");
			btnSave.addActionListener(this);
			btnSave.setBounds(L_X + L_W + C_W + 10 + 50, 73, 100, 25);
			getContentPane().add(btnSave);
		}

		// Устанавливаем поведение формы при закрытии - не закрывать совсем.
		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

		// Получаем размеры экрана
		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		// А теперь просто помещаем его по центру, вычисляя координаты на основе полученной информации
		setBounds(((int) d.getWidth() - WinReader.D_WIDTH) / 2, ((int) d.getHeight() - WinReader.D_HEIGHT) / 2, WinReader.D_WIDTH, WinReader.D_HEIGHT);

	}

	// Получить результат, true - кнопка ОК, false - кнопка Выход
	public boolean getResult()
	{
		return result;
	}

	// Установить поля соответственно переданным данным о читателе
	public void setReader(Reader rdr)
	{
		readerId = rdr.getReaderId();
		readerFam.setText(rdr.getReaderFam());
		readerName.setText(rdr.getReaderName());
		readerOtch.setText(rdr.getReaderOtch());
		readerBirthday.getModel().setValue(rdr.getReaderBirthday());
		readerDateReg.getModel().setValue(rdr.getReaderDateReg());
		readerPassport.setText(rdr.getReaderPassport());
		readerAdress.setText(rdr.getReaderAdress());
		readerPhone.setText(rdr.getReaderPhone());

	}

	// Вернуть данные в виде нового читателя с соотвтествующими полями
	public Reader getReader()
	{
		Reader rdr = new Reader();
		rdr.setReaderId(readerId);
		rdr.setReaderFam(readerFam.getText());
		rdr.setReaderName(readerName.getText());
		rdr.setReaderOtch(readerOtch.getText());

		Date dateBirthday = ((SpinnerDateModel) readerBirthday.getModel()).getDate();
		rdr.setReaderBirthday(dateBirthday);

		Date dateReg = ((SpinnerDateModel) readerDateReg.getModel()).getDate();
		rdr.setReaderDateReg(dateReg);

		rdr.setReaderPassport(readerPassport.getText());
		rdr.setReaderAdress(readerAdress.getText());
		rdr.setReaderPhone(readerPhone.getText());
		return rdr;
	}

	public void actionPerformed(ActionEvent aE)
	{
		JButton src = (JButton) aE.getSource();
		// Добавляем читателя, но не закрываем окно
		// Здесь мы не будем вызывать в отдельном потоке сохранение.
		// Оно не занимает много времени и лишние действия здесь не оправданы
		if (src.getName().equals("Добавить"))
		{
			result = true;
			try
			{
				ManagementSystem.getInstance().insertReader(getReader());
				reloadReaders();
				readerFam.setText("");
				readerName.setText("");
				readerOtch.setText("");
				readerBirthday = new JSpinner(new SpinnerDateModel(new Date(), null, null, Calendar.DAY_OF_MONTH));
				readerDateReg = new JSpinner(new SpinnerDateModel(new Date(), null, null, Calendar.DAY_OF_MONTH));
				readerPassport.setText("");
				readerAdress.setText("");
				readerPhone.setText("");
			}
			catch (Exception sql_e)
			{
				JOptionPane.showMessageDialog(this, sql_e.getMessage());
			}
			return;
		}
		if (src.getName().equals("Сохранить"))
		{
			result = true;
			try
			{
				ManagementSystem.getInstance().updateReader(getReader());
				reloadReaders();
			}
			catch (Exception sql_e)
			{
				JOptionPane.showMessageDialog(this, sql_e.getMessage());
			}
			return;
		}
		if (src.getName().equals("Удалить"))
		{

			result = true;
			deleteReader();
			readerFam.setText("");
			readerName.setText("");
			readerOtch.setText("");
			readerBirthday = new JSpinner(new SpinnerDateModel(new Date(), null, null, Calendar.DAY_OF_MONTH));
			readerDateReg = new JSpinner(new SpinnerDateModel(new Date(), null, null, Calendar.DAY_OF_MONTH));
			readerPassport.setText("");
			readerAdress.setText("");
			readerPhone.setText("");
			return;

		}

		// Смена ФЛАГА
		if (src.getName().equals("OK"))
		{
			result = true;
		}
		if (src.getName().equals("Выход"))
		{
			result = false;
		}
		setVisible(false);
	}

	// метод для удаления исполнителя
	private void deleteReader()
	{
		try
		{
			ms = new ManagementSystem();
			Thread t = new Thread()
			{
				public void run()
				{
					if (readersTab != null)
					{
						ReaderTableModel stm = (ReaderTableModel) readersTab.getModel();
						// Проверяем - выделен ли хоть какой-нибудь читатель
						if (readersTab.getSelectedRow() >= 0)
						{
							if (JOptionPane.showConfirmDialog(WinReader.this,
									"<html><font color=red>Вы хотите удалить читателя?", "Удаление читателя",
									JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
							{
								Reader reader = stm.getReader(readersTab.getSelectedRow());
								try
								{
									ms.deleteReader(reader);
									reloadReaders();
								}
								catch (SQLException e)
								{
									JOptionPane.showMessageDialog(WinReader.this, e.getMessage());
								}
							}
						} // Если читатель не выделен - сообщаем пользователю, что это необходимо
						else
						{
							JOptionPane.showMessageDialog(WinReader.this, "Необходимо выделить читателя в списке");
						}

					}
				}
			};
			t.start();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Метод для обеспечения интерфейса ListSelectionListener
 	 */
	public void valueChanged(ListSelectionEvent e)
	{
		if (!e.getValueIsAdjusting())
		{
			reloadReaders();
		}

	}

	/**
	 *  метод для обновления списка ЧИТАТЕЛЕЙ
	 */
	public void reloadReaders()
	{
		// Создаем анонимный класс для потока
		Thread t = new Thread()
		{
			// Переопределяем в нем метод run
			public void run()
			{
				if (readersTab != null)
				{
					try
					{
						// Получаем список читателей
						Collection<Reader> lRead = ms.getReaders();
						// И устанавливаем модель для таблицы с новыми данными
						readersTab.setModel(new ReaderTableModel(new Vector<Reader>(lRead)));
					}
					catch (SQLException e)
					{
						JOptionPane.showMessageDialog(WinReader.this, e.getMessage());
					}
				}
			}
		};
		// И теперь мы запускаем наш поток
		t.start();
	}

	/**
	 * Метод для обеспечения интерфейса ChangeListener
	 * @param e
	 */
	public void stateChanged(ChangeEvent e)
	{
		reloadReaders();
	}

	/**
	 * Метод слушателя строк`
	 */
	private class RowListener implements ListSelectionListener
	{

		public void valueChanged(ListSelectionEvent event)
		{
			ReaderTableModel ctm = (ReaderTableModel) readersTab.getModel();
			Reader cl = ctm.getReader(readersTab.getSelectedRow());

			if (event.getValueIsAdjusting())
			{
				return;
			}
			try
			{
				setReader(cl);
			}
			catch (Exception sql_e)
			{
				JOptionPane.showMessageDialog(WinReader.this, "Данные успешно сохранены");
			}
		}
	}
}
